<!-- $Id: doc.html,v 1.5 1995/04/07 22:19:39 chris Exp $ -->
<HTML>
<HEAD>
<TITLE>Parser API</TITLE>
</HEAD>
<BODY>
<HR>
<H1>HTML Parser</H1>
<P>
The following document describes the various parts that make
up the HTML parser and dtd library.
These components can be used to provide html parsing and
information about the HTML 2.0 DTD.
Functions are provided to allow for error handling and
modification of the DTD to add extensions.
</P>

<HR>
<H2>Function Index</H2>
<MENU>
<LI><A HREF="#AddElementChild">AddElementChild</A></LI>
<LI><A HREF="#AddElementParent">AddElementParent</A></LI>
<LI><A HREF="#ChangeElementInfo">ChangeElementInfo</A></LI>
<LI><A HREF="#GetAtom">GetAtom</A></LI>
<LI><A HREF="#GetAtomVal">GetAtomVal</A></LI>
<LI><A HREF="#GetElementAttrInfo">GetElementAttrInfo</A></LI>
<LI><A HREF="#GetElementAttrList">GetElementAttrList</A></LI>
<LI><A HREF="#GetElementChildren">GetElementChildren</A></LI>
<LI><A HREF="#GetElementFixedAttrs">GetElementFixedAttrs</A></LI>
<LI><A HREF="#GetElementImpliedAttrs">GetElementImpliedAttrs</A></LI>
<LI><A HREF="#GetElementInfo">GetElementInfo</A></LI>
<LI><A HREF="#GetElementParents">GetElementParents</A></LI>
<LI><A HREF="#GetElementReqAttrs">GetElementReqAttrs</A></LI>
<LI><A HREF="#GetElementTerminator">GetElementTerminator</A></LI>
<LI><A HREF="#HTMLDeleteBFlags">HTMLDeleteBFlags</A></LI>
<LI><A HREF="#HTMLFreeAttribute">HTMLFreeAttribute</A></LI>
<LI><A HREF="#HTMLFreeAttributeList">HTMLFreeAttributeList</A></LI>
<LI><A HREF="#HTMLFreeBlock">HTMLFreeBlock</A></LI>
<LI><A HREF="#HTMLFreeParseTree">HTMLFreeParseTree</A></LI>
<LI><A HREF="#HTMLFreeTree">HTMLFreeTree</A></LI>
<LI><A HREF="#HTMLGetAAtom">HTMLGetAAtom</A></LI>
<LI><A HREF="#HTMLGetAData">HTMLGetAData</A></LI>
<LI><A HREF="#HTMLGetALineno">HTMLGetALineno</A></LI>
<LI><A HREF="#HTMLGetAName">HTMLGetAName</A></LI>
<LI><A HREF="#HTMLGetANext">HTMLGetANext</A></LI>
<LI><A HREF="#HTMLGetAttr">HTMLGetAttr</A></LI>
<LI><A HREF="#HTMLGetBAtom">HTMLGetBAtom</A></LI>
<LI><A HREF="#HTMLGetBAttrs">HTMLGetBAttrs</A></LI>
<LI><A HREF="#HTMLGetBChild">HTMLGetBChild</A></LI>
<LI><A HREF="#HTMLGetBData">HTMLGetBData</A></LI>
<LI><A HREF="#HTMLGetBFlags">HTMLGetBFlags</A></LI>
<LI><A HREF="#HTMLGetBLineno">HTMLGetBLineno</A></LI>
<LI><A HREF="#HTMLGetBParent">HTMLGetBParent</A></LI>
<LI><A HREF="#HTMLGetBSib">HTMLGetBSib</A></LI>
<LI><A HREF="#HTMLGetBType">HTMLGetBType</A></LI>
<LI><A HREF="#HTMLInsertBlock">HTMLInsertBlock</A></LI>
<LI><A HREF="#HTMLNewAttr">HTMLNewAttr</A></LI>
<LI><A HREF="#HTMLNewBlock">HTMLNewBlock</A></LI>
<LI><A HREF="#HTMLParseBegin">HTMLParseBegin</A></LI>
<LI><A HREF="#HTMLParseDo">HTMLParseDo</A></LI>
<LI><A HREF="#HTMLParseEnd">HTMLParseEnd</A></LI>
<LI><A HREF="#HTMLRemoveAttr">HTMLRemoveAttr</A></LI>
<LI><A HREF="#HTMLRemoveBlock">HTMLRemoveBlock</A></LI>
<LI><A HREF="#HTMLSetAAtom">HTMLSetAAtom</A></LI>
<LI><A HREF="#HTMLSetAData">HTMLSetAData</A></LI>
<LI><A HREF="#HTMLSetALineno">HTMLSetALineno</A></LI>
<LI><A HREF="#HTMLSetAName">HTMLSetAName</A></LI>
<LI><A HREF="#HTMLSetANext">HTMLSetANext</A></LI>
<LI><A HREF="#HTMLSetAttr">HTMLSetAttr</A></LI>
<LI><A HREF="#HTMLSetBAtom">HTMLSetBAtom</A></LI>
<LI><A HREF="#HTMLSetBAttrs">HTMLSetBAttrs</A></LI>
<LI><A HREF="#HTMLSetBChild">HTMLSetBChild</A></LI>
<LI><A HREF="#HTMLSetBData">HTMLSetBData</A></LI>
<LI><A HREF="#HTMLSetBFlags">HTMLSetBFlags</A></LI>
<LI><A HREF="#HTMLSetBLineno">HTMLSetBLineno</A></LI>
<LI><A HREF="#HTMLSetBParent">HTMLSetBParent</A></LI>
<LI><A HREF="#HTMLSetBSib">HTMLSetBSib</A></LI>
<LI><A HREF="#HTMLSetBType">HTMLSetBType</A></LI>
<LI><A HREF="#HTMLSetErrorHand">HTMLSetErrorHand</A></LI>
<LI><A HREF="#InitDTD">InitDTD</A></LI>
<LI><A HREF="#IsEleMandTermed">IsEleMandTermed</A></LI>
<LI><A HREF="#IsEleNoneTermed">IsEleNoneTermed</A></LI>
<LI><A HREF="#IsEleOptTermed">IsEleOptTermed</A></LI>
<LI><A HREF="#IsElementImplied">IsElementImplied</A></LI>
<LI><A HREF="#ValidAttribute">ValidAttribute</A></LI>
<LI><A HREF="#ValidRelationship">ValidRelationship</A></LI>
</MENU>
<HR>
<H2><A NAME="Atoms">Atoms</A></H2>
<P>
Atoms are used to represent all element and attribute keywords
in the parser and dtd.
Atoms will also be used to represent some values of attributes
(like TOP, MIDDLE, and COMPACT), but will not be used for
quoted strings.
All strings are treated as case-insensitive when <A HREF="#Atoms">atoms</A> are
processed.
The <A HREF="#Atoms">atom</A> handling functions are provided by libdtd.a.
It is advisable that the DTD call <A HREF="#InitDTD">InitDTD()</A> be made before calling
<A HREF="#Atoms">atom</A> functions since it will initialize the basic HTML <A HREF="#Atoms">atoms</A>.
</P>
<H3>Atom Functions</H3>
<H4><A NAME="GetAtom">GetAtom</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> GetAtom(char *string)
</P>
<H5>Description</H5>
<P>
The passed string will compared against the list of existing <A HREF="#Atoms">atoms</A>.
If a match is found, that <A HREF="#Atoms">atom</A> value is returned, otherwise a new
<A HREF="#Atoms">atom</A> is created and the value is returned.
</P>
<H4><A NAME="GetAtomVal">GetAtomVal</A></H4>
<H5>Usage</H5>
<P>
char *GetAtomVal(<A HREF="#Atoms">atom</A> at)
</P>
<H5>Description</H5>
<P>
The character string associated with the <A HREF="#Atoms">atom</A> will be returned.
</P>

<HR>
<H2>DTD Library</H2>
<P>
The DTD library (libdtd.a) provides an API for getting information
about the HTML DTD.
The functions in it reference a table built from the HTML DTD.
</P>
<H3>DTD Data Structures</H3>
<H4><A NAME="DTDAttribute">DTD Attribute Data Structure</A></H4>
<PRE><CODE>
typedef struct dtd_attribute {
    <A HREF="#Atom">atom</A> name;
    int type;
#define A_REQUIRED      1
#define A_FIXED         2
#define A_IMPLIED       3
    unsigned int valid;
#define AF_DATATYPE     0x1
#define AF_LIST         0x2
#define AF_DEFSTRING    0x4
#define AF_DEFATOM      0x8
    <A HREF="#Atom">atom</A> dataType;
    <A HREF="#Atom">atom</A> list[10];
    char *defString;
    <A HREF="#Atom">atom</A> defAtom;
} DTDAttribute;
</CODE></PRE>
<DL>
<DT>name</DT>
<DD>Atom for the attribute name string.</DD>
<DT>type</DT>
<DD>What type of attribute this is.
Should be A_REQUIRED, A_FIXED, or A_IMPLIED.</DD>
<DT>valid</DT>
<DD>Which of the following fields are valid.
(Different attributes use different combinations of these fields.)</DD>
<DT>dataType</DT>
<DD>Atom representing data type.</DD>
<DT>list</DT>
<DD>List of <A HREF="#Atoms">atoms</A> which can be used as the value of this attribute.</DD>
<DT>defString</DT>
<DD>Default character string for this attribute.</DD>
<DT>defAtom</DT>
<DD>Default <A HREF="#Atoms">atom</A> for this attribute.</DD>
</DL>
<H4><A NAME="DTDElement">DTD Element Data Structure</A></H4>
<PRE><CODE>
typedef struct dtd_element {
    <A HREF="#Atom">atom</A> name;
    int flags;
#define E_TERM_MAND     0x001
#define E_TERM_NONE     0x002
#define E_TERM_OPT      0x004
#define E_ELE_OPT       0x008
    <A HREF="#Atom">atom</A> children[40];          /* Allowed children */
    <A HREF="#Atom">atom</A> parents[40];           /* Allowed parents */
    <A HREF="#DTDAttribute">DTDAttribute</A> attrs[10];     /* Attribute details (info) list */
    <A HREF="#Atom">atom</A> attrList[10];          /* Attribute <A HREF="#Atoms">atom</A> list */
    <A HREF="#Atom">atom</A> reqAttrs[10];          /* Required Attributes */
    <A HREF="#Atom">atom</A> fixedAttrs[10];        /* Fixed Attributes */
    <A HREF="#Atom">atom</A> impliedAttrs[10];      /* Implied Attributes */
} DTDElement;
</CODE></PRE>
<DL>
<DT>name</DT>
<DD>Atom for the element name string.</DD>
<DT>flags</DT>
<DD>Flags for this element.</DD>
<DT>children</DT>
<DD>Atoms for elements that can be contained in this element.</DD>
<DT>parents</DT>
<DD>Atoms for elements that can contain this element.</DD>
<DT>attrs</DT>
<DD>Array of DTDAttribute structures for all attributes allowed in
this element.</DD>
<DT>attrList</DT>
<DD>Atom list of attributes.</DD>
<DT>reqAttrs</DT>
<DD>Atom list of required attributes.</DD>
<DT>fixedAttrs</DT>
<DD>Atom list of fixed attributes.</DD>
<DT>impliedAttrs</DT>
<DD>Atom list of implied attributes.</DD>
</DL>
<H3>DTD Macros</H3>
<P>
All DTD macros operate on <A HREF="#Atoms">atoms</A>.
</P>
<H4><A NAME="IsEleOptTermed">IsEleOptTermed</A></H4>
<H5>Usage</H5>
<P>
IsEleOptTermed(element)
</P>
<H5>Description</H5>
<P>
Does this element have an optional terminator?
</P>
<H4><A NAME="IsEleMandTermed">IsEleMandTermed</A></H4>
<H5>Usage</H5>
<P>
IsEleMandTermed(element)
</P>
<H5>Description</H5>
<P>
Does this element have a manditory terminator?
</P>
<H4><A NAME="IsEleNoneTermed">IsEleNoneTermed</A></H4>
<H5>Usage</H5>
<P>
IsEleNoneTermed(element)
</P>
<H5>Description</H5>
<P>
Does this element have a no terminator?
</P>
<H4><A NAME="IsElementImplied">IsElementImplied</A></H4>
<H5>Usage</H5>
<P>
IsElementImplied(element)
</P>
<H5>Description</H5>
<P>
Can this element be implied by other elements?
</P>
<H4><A NAME="ValidAttribute">ValidAttribute</A></H4>
<H5>Usage</H5>
<P>
ValidAttribute(element, attr)
</P>
<H5>Description</H5>
<P>
Is this attribute a valid attribute in this element?
</P>
<H3>DTD Library Functions</H3>
<H4><A NAME="InitDTD">InitDTD</A></H4>
<H5>Usage</H5>
<P>
void InitDTD();
</P>
<H5>Description</H5>
<P>
InitDTD() is called to initialize the <A HREF="#Atoms">atom</A> table and the HTML element
lists.
It must be called before using any other functions in libdtd.a or
errors will result.
</P>
<H4><A NAME="ChangeElementInfo">ChangeElementInfo</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#DTDElement">DTDElement</A>
*ChangeElementInfo(<A HREF="#Atoms">atom</A> element, <A HREF="#DTDElement">DTDElement</A> *new);
</P>
<H5>Description</H5>
<P>
ChangeElementInfo() may be called to change or set the element data
associated with a give element.
It returns a pointer to the structure formerly associated with that
element.
The returned structure can freed using free().
All future information function calls will use the new structure
to provide information for that element.
</P>
<H4><A NAME="AddElementChild">AddElementChild</A></H4>
<H5>Usage</H5>
<P>
int AddElementChild(<A HREF="#Atoms">atom</A> element, <A HREF="#Atoms">atom</A> child);
</P>
<H5>Description</H5>
<P>
Adds a new <A HREF="#Atoms">atom</A> as a child of this element by appending it to the children
list.
Return the number of children in the element or 0 on error.
</P>
<H4><A NAME="AddElementParent">AddElementParent</A></H4>
<H5>Usage</H5>
<P>
int AddElementParent(<A HREF="#Atoms">atom</A> element, <A HREF="#Atoms">atom</A> parent);
</P>
<H5>Description</H5>
<P>
Adds a new <A HREF="#Atoms">atom</A> as a parent to this element by appending it to the parent
list.
Return the number of parents in the element or 0 on error.
</P>
<H4><A NAME="GetElementChildren">GetElementChildren</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementChildren(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of element <A HREF="#Atoms">atoms</A> allowed in the
argument element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementParents">GetElementParents</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementParents(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of element <A HREF="#Atoms">atoms</A> which the
argument element is allowed in.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementAttrList">GetElementAttrList</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementAttrList(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of all attributes in the
argument element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementAttrInfo">GetElementAttrInfo</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#DTDAttribute">DTDAttribute</A>
*GetElementAttrInfo(<A HREF="#Atoms">atom</A> element, <A HREF="#Atoms">atom</A> attr);
</P>
<H5>Description</H5>
<P>
Get the full attribute structure for attribute attr in
the argument element.
If the attribute or element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementReqAttrs">GetElementReqAttrs</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementReqAttrs(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of required attributes for the
argument element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementFixedAttrs">GetElementFixedAttrs</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementFixedAttrs(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of fixed attributes for the
argument element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementImpliedAttrs">GetElementImpliedAttrs</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#Atoms">atom</A> *GetElementImpliedAttrs(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get a zero (0) terminated list of implied attributes for the
argument element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="GetElementTerminator">GetElementTerminator</A></H4>
<H5>Usage</H5>
<P>
int GetElementTerminator(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Get the termination type for this element.
It can be one of E_TERM_MAND, E_TERM_NONE, or E_TERM_OPT.
If the element is unknown this function returns E_TERM_MAND.
</P>
<H4><A NAME="GetElementInfo">GetElementInfo</A></H4>
<H5>Usage</H5>
<P>
<A HREF="#DTDElement">DTDElement</A>
*GetElementInfo(<A HREF="#Atoms">atom</A> element);
</P>
<H5>Description</H5>
<P>
Return the
<A HREF="#DTDElement">DTDElement</A>
structure associated with this element.
If the element is unknown this function returns zero.
</P>
<H4><A NAME="ValidRelationship">ValidRelationship</A></H4>
<H5>Usage</H5>
<P>
int ValidRelationship(<A HREF="#Atoms">atom</A> parent, <A HREF="#Atoms">atom</A> child);
</P>
<H5>Description</H5>
<P>
Return one (1) if the child element is a valid child of
the parent element.  Otherwise return zero (0).
If the element is unknown this function returns one, thus
allowing unknown elements to be parented by any other element.
</P>

<HR>
<H2>Parser Library</H2>
<P>
The parser is provided by the libhtml.a library.
It requires the libdtd.a library.
</P>
<H3>Parser Functions</H3>
<P>
The parser is driven by three functions which must be called
in a specific order.
The final function will return a pointer to the block representing
the top of the parse tree.
That block is empty accept for the child pointer which will point
to the first element in the document.
</P>
<H4><A NAME="HTMLParseBegin">HTMLParseBegin</A></H4>
<H5>Usage</H5>
<P>
void HTMLParseBegin();
</P>
<H5>Description</H5>
<P>
Sets up the parser.
</P>
<H4><A NAME="HTMLParseDo">HTMLParseDo</A></H4>
<H5>Usage</H5>
<P>
void HTMLParseDo(FILE *yyin);
</P>
<H5>Description</H5>
<P>
Runs the parser on the provided input file creating a parse tree.
</P>
<H4><A NAME="HTMLParseEnd">HTMLParseEnd</A></H4>
<H5>Usage</H5>
<P>
Block *HTMLParseEnd();
</P>
<H5>Description</H5>
<P>
Checks for missing information in the parse tree (like the required
&lt;TITLE> markup) and other errors.
Returns a pointer the final tree.
</P>
<HR>
<H4><A NAME="HTMLFreeParseTree">HTMLFreeParseTree</A></H4>
<H5>Usage</H5>
<P>
Block *HTMLFreeParseTree();
</P>
<H5>Description</H5>
<P>
Frees all space allocated in the parse tree returned by HTMLParseEnd().
</P>

<HR>
<H2>Markups</H2>
<P>
A block is our basic data structure.
A block can be one of four types, including an element tag,
character text, a comment, or a doctype declaration.  
</P>
<P>
We build a tree of blocks containing the document hierarchy.
Each block can have a set of children
below it, plus a set of siblings at the same level.
To traverse the tree, one would start with the markup, then
handle the children, and finally handle all siblings.
</P>
<H3>Markup Data Structure</H3>
<P>
The following is the markup data structure.
All accesses to this structure should use the macros defined below.
</P>
<PRE><CODE>
typedef struct block {
    int type;
#define TAG		1
#define PCDATA	2
#define CMNT		3
#define DOCTYPE		4
    int flags;			/* Special flags */
#define OPTCLOSE	0x01	/* input lacked optional close for this block */
#define OPTTAG		0x02	/* input lacked this optional tag (HTML....) */
#define SHRTTAG		0x04	/* This tag was closed with shorttag &lt;/> */
#define PRETTYSTART	0x10	/* This tag was followed by a newline */
#define PRETTYEND	0x20	/* This tag end was followed by a newline */
    <A HREF="#Atom">atom</A> bAtom;			/* atom for this element */
    char *data;			/* Text or tag name */
    int lineno;			/* tag start Input file line number */
    <A HREF="#Attribute Data Structure">Attribute</A> *attrs;
    struct block *next_sib;	/* sibling on right */
    struct block *children;	/* children below */
    struct block *parent;
} Block;
</CODE></PRE>
<DL>
<DT>type</DT>
<DD>What type of document structure this block contains.</DD>
<DT>flags</DT>
<DD>Special information flags about the block.
Currently keeps track of whether the markup was created or
terminated implicitly.</DD>
<DT>bAtom</DT>
<DD>Atom for this element.</DD>
<DT>data</DT>
<DD>Either the original markup string or the text or comment data.</DD>
<DT>lineno</DT>
<DD>Line number in source file which the data started on.</DD>
<DT>attr</DT>
<DD>Points to an optional list of
<A HREF="#Attribute Data Structure">attributes</A>
associated with this markup block.</DD>
<DT>next_sib</DT>
<DD>points to the next block on a list of blocks that share
this block's parent.</DD>
<DT>children</DT>
<DD>Points to this markup's first child.
All other children will be pointed to by this child's next_sib.</DD>
<DT>parent</DT>
<DD>Points to this markup's parent.</DD>
</DL>

<H3>Markup Macros</H3>
<H4><A NAME="HTMLGetBAtom">HTMLGetBAtom</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBAtom(block)
</P>
<H5>Description</H5>
<P>
Get the <A HREF="#Atoms">atom</A> for this markup.
GetAtomVal() can be used to get the actual character string.
This field is only valid when type is TAG.
</P>

<H4><A NAME="HTMLGetBType">HTMLGetBType</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBType(block)
</P>
<H5>Description</H5>
<P>
Get the type for this block.
The type can be any of four types:
</P>
<DL>
<DT>TAG</DT>
<DD>This block is a markup</DD>
<DT>PCDATA</DT>
<DD>This block contains regular character text</DD>
<DT>CMNT</DT>
<DD>This block contains a comment</DD>
<DT>DOCTYPE</DT>
<DD>This block contains the data from a DOCTYPE line</DD>
</DL>

<H4><A NAME="HTMLGetBData">HTMLGetBData</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBData(block)
</P>
<H5>Description</H5>
<P>
This returns the data from the this block.
For TAG this will contain the raw markup name from the source.
For the other block types, it will contain the character data
for that type.
</P>

<H4><A NAME="HTMLGetBParent">HTMLGetBParent</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBParent(block)
</P>
<H5>Description</H5>
<P>
All blocks know who their parent is.
This macro returns that value.
</P>

<H4><A NAME="HTMLGetBChild">HTMLGetBChild</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBChild(block)
</P>
<H5>Description</H5>
<P>
This macro returns the first child of the block (as determined by the
parse structure).
All other children of this block can be obtained by following the
sibling pointer from the child.
If a block has no children, this macro returns 0.
</P>

<H4><A NAME="HTMLGetBSib">HTMLGetBSib</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBSib(block)
</P>
<H5>Description</H5>
<P>
Get the next sibling for this block.
All siblings share the same parent.
If this block is the last child (or sibling), this macro will
return 0.
</P>

<H4><A NAME="HTMLGetBLineno">HTMLGetBLineno</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBLineno(block)
</P>
<H5>Description</H5>
<P>
Get the line number this block started (ended?) on.
Dynamically created blocks should return a value of 0.
</P>

<H4><A NAME="HTMLGetBFlags">HTMLGetBFlags</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBFlags(block)
</P>
<H5>Description</H5>
<P>
Get the flags associated with this block.
</P>
<DL>
<DT>OPTCLOSE</DT>
<DD>This markup's closing was inferred from context rather than found
in the source.</DD>
<DT>OPTTAG</DT>
<DD>This markup never appeared in the source, but was inferred by another
markup type.</DD>
<DT>SHRTTAG</DT>
<DD>This tag was closed with shorttag &lt;/></DD>
<DT>PRETTYSTART</DT>
<DD>This tag was followed by a newline.
This information is most useful for programs that want
to print the source document out basically in the same
format in which it was inputed.</DD>
<DT>PRETTYEND</DT>
<DD>This tag end was followed by a newline.
This information is most useful for programs that want
to print the source document out basically in the same
format in which it was inputed.</DD>
</DL>

<H4><A NAME="HTMLGetBAttrs">HTMLGetBAttrs</A></H4>
<H5>Usage</H5>
<P>
HTMLGetBAttrs(block)
</P>
<H5>Description</H5>
<P>
This macro returns the
<A HREF="#Attribute Data Structure">attribute</A> list.
</P>

<H4><A NAME="HTMLSetBAtom">HTMLSetBAtom</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBAtom(block, _atom)
</P>
<H5>Description</H5>
<P>
Set the <A HREF="#Atoms">atom</A> value for a block.
This macro is of limited use since there is other data in the block
that may not be appropriate for the new markup type.
More common would be to replace the entire block with one or more
new ones.
</P>

<H4><A NAME="HTMLSetBType">HTMLSetBType</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBType(block, _type)
</P>
<H5>Description</H5>
<P>
Set the block's type.
Also of limited use.
Types available are:
</P>
<DL>
<DT>TAG</DT>
<DD>This block is a markup</DD>
<DT>PCDATA</DT>
<DD>This block contains regular character text</DD>
<DT>CMNT</DT>
<DD>This block contains a comment</DD>
<DT>DOCTYPE</DT>
<DD>This block contains the data from a DOCTYPE line</DD>
</DL>

<H4><A NAME="HTMLSetBData">HTMLSetBData</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBData(block, _data)
<H5>Description</H5>
<P>
Set the data for the given block.
</P>

<H4><A NAME="HTMLSetBParent">HTMLSetBParent</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBParent(block, _parent)
</P>
<H5>Description</H5>
<P>
Set the parent for the given block.
</P>

<H4><A NAME="HTMLSetBChild">HTMLSetBChild</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBChild(block, _child)
</P>
<H5>Description</H5>
<P>
Set the child field for the given block to block _child.
This macro doesn't do insertion.
It simply sets the structure field.
<A HREF="#HTMLInsertBlock">HTMLInsertBlock</A> should be used to
insert a block into the parse tree.
</P>

<H4><A NAME="HTMLSetBSib">HTMLSetBSib</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBSib(block, _sib)
</P>
<H5>Description</H5>
<P>
Set the next sibling field for the given block to block _sib.
This macro doesn't do insertion.
It simply sets the structure field.
<A HREF="#HTMLInsertBlock">HTMLInsertBlock</A> should be used to
insert a block into the parse tree.
</P>

<H4><A NAME="HTMLSetBLineno">HTMLSetBLineno</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBLineno(block, _lineno)
</P>
<H5>Description</H5>
<P>
Set the line number for this block.
This is of limited use.
Blocks created dynamically should use a line number of 0.
</P>

<H4><A NAME="HTMLSetBAttrs">HTMLSetBAttrs</A></H4>
<H5>Usage</H5>
<P>
HTMLSetBAttrs(block, _attrs)
</P>
<H5>Description</H5>
<P>
Set the <A HREF="#Attribute Data Structure">attribute</A> list for a block.
_attrs is a list of one or more
<A HREF="#Attribute Data Structure">attributes</A>.
</P>

<H4><A NAME="HTMLSetBFlags">HTMLSetBFlags</A></H4>
<H5>Usage</H5>
<P>
HTMLAddBFlags(block, _flags)
</P>
<H5>Description</H5>
<P>
HTMLAddBFlags sets the flags specified in _flags.
This macro does a binary OR operation, so other set flags will remain set.
</P>

<H4><A NAME="HTMLDeleteBFlags">HTMLDeleteBFlags</A></H4>
<H5>Usage</H5>
<P>
HTMLDeleteBFlags(block, _flags)
</P>
<H5>Description</H5>
<P>
HTMLAddBFlags turns off the flags specified in _flags.
This macro does a binary &~ operation, so other set flags will remain set.
</P>

<H3>Markup Functions</H3>
<P>
These markup function calls are used mostly to modify a document
parse tree.
They provide creation/destruction, and manipulation functions.

<H4><A NAME="HTMLNewBlock">HTMLNewBlock</A></H4>
<H5>Usage</H5>
<P>
Block *HTMLNewBlock(int type, char *data, int lineno);
<H5>Description</H5>
<P>
HTMLNewBlock returns a pointer to a new structure.
The caller needs to provide type and data.
Lineno should be zero.
If type is TAG, HTMLNewBlock will lookup the <A HREF="#Atoms">atom</A> for it.
The data should have been allocated with malloc().

<H4><A NAME="HTMLFreeBlock">HTMLFreeBlock</A></H4>
<H5>Usage</H5>
<P>
void HTMLFreeBlock(Block *old);
<H5>Description</H5>
<P>
Free the passed block and contained data.
HTMLFreeBlock will not free children or siblings.
It does free the attribute list.

<H4><A NAME="HTMLFreeTree">HTMLFreeTree</A></H4>
<H5>Usage</H5>
<P>
void HTMLFreeTree(Block *old);
<H5>Description</H5>
<P>
Free the passed block and all children and sibling blocks.

<H4><A NAME="HTMLInsertBlock">HTMLInsertBlock</A></H4>
<H5>Usage</H5>
<P>
void HTMLInsertBlock(Block *bp, Block *parent, Block *predecessor);
<H5>Description</H5>
<P>
HTMLInsertBlock inserts the passed block into the parse tree, using
parent as the parent and predecessor as the immediately preceding
child.
If parent is NULL, it will default to the parent of the predecessor.
If predecessor is NULL, it will become the child of the parent and
move the current child to its sibling list (if necessary).
Arguments parent and predecessor cannot both be NULL.

<H4><A NAME="HTMLRemoveBlock">HTMLRemoveBlock</A></H4>
<H5>Usage</H5>
<P>
Block *HTMLRemoveBlock(Block *bp);
<H5>Description</H5>
<P>
Remove this block from the parse tree.
This block's siblings will be reattached correctly, but the block's
children cannot be easily reattached.
HTMLRemoveBlock returns a pointer to the block's first child.
HTMLRemoveBlock does not free any storage.

<HR>
<H2>Markup Attributes</H2>
<P>
Markups can contain zero or more attributes, each containing an optional
keyword and a manditory value.
The value may or may not be quoted.
In some cases its the possible values for a give attribute are limited.
In others the value can be an arbitrary string.
For a given markup, we create a list of attributes.
HTMLGetBAttrs() can be used to obtain the first element of the list
from a markup block.
</P>
<H3><A NAME="Attribute Data Structure">Attribute Data Structure</A></H3>
<P>
The following is the attribute structure.
All accesses to this structure should use the macros defined below.
</P>
<PRE><CODE>
typedef struct attribute {
    <A HREF="#Atom">atom</A> aAtom;			/* Attribute atom */
    int lineno;			/* attribute line number */
    int flags;			/* Special flags */
#define DQUOTEDVALUE	0x1	/* attribute value was double-quoted */
#define SQUOTEDVALUE	0x2	/* attribute value was single-quoted */
    char *name;			/* Name like 'href' */
    char *data;			/* string of value (NULL if no value defined) */
    struct attribute *next;	/* unlimited number of attributes */
} Attribute;
</CODE></PRE>
<DL>
<DT>aAtom</DT>
<DD>Atom associated with attribute name.</DD>
<DT>lineno</DT>
<DD>Line number in source file which the attribute started on.</DD>
<DT>flags</DT>
<DD>Special information flags about the attribute.
Currently keeps track of whether the attribute value was enclosed
in single or double quotes.</DD>
<DT>name</DT>
<DD>Contains a pointer to the attribute name string as it appeared in the
source file.</DD>
<DT>data</DT>
<DD>Contains a pointer to the value as it appeared in the
source file (but without quotes).</DD>
<DT>next</DT>
<DD>Contains a pointer to the next attribute in the list.</DD>
</DL>

<H3>Attribute Macros</H3>
<H4><A NAME="HTMLGetAAtom">HTMLGetAAtom</A></H4>
<H5>Usage</H5>
<P>
HTMLGetAAtom(attribute)
</P>
<H5>Usage</H5>
<P>
Return the <A HREF="#Atoms">atom</A> value for an attribute.
</P>
<H4><A NAME="HTMLGetAName">HTMLGetAName</A></H4>
<H5>Usage</H5>
<P>
HTMLGetAName(attribute)
</P>
<H5>Description</H5>
<P>
Return the source file name for an attribute.
Note that the source file name could have weird character cases:
i.e. HrEf=foo
</P>
<H4><A NAME="HTMLGetAData">HTMLGetAData</A></H4>
<H5>Usage</H5>
<P>
HTMLGetAData(attribute)
</P>
<H5>Description</H5>
<P>
Return the value string for an attribute
</P>
<H4><A NAME="HTMLGetANext">HTMLGetANext</A></H4>
<H5>Usage</H5>
<P>
HTMLGetANext(attribute)
</P>
<H5>Description</H5>
<P>
Return the next attribute in the list.
0 is returned when there are no further attributes.
</P>
<H4><A NAME="HTMLGetALineno">HTMLGetALineno</A></H4>
<H5>Usage</H5>
<P>
HTMLGetALineno(attribute)
<H5>Description</H5>
<P>
Return the source file line number this attribute appeared on.
A line number value of 0 represents an unknown location.
</P>
<H4><A NAME="HTMLSetAAtom">HTMLSetAAtom</A></H4>
<H5>Usage</H5>
<P>
HTMLSetAAtom(attribute, _atom)
</P>
<H5>Description</H5>
<P>
Set the attribute <A HREF="#Atoms">atom</A> value.
</P>
<H4><A NAME="HTMLSetAName">HTMLSetAName</A></H4>
<H5>Usage</H5>
<P>
HTMLSetAName(attribute, _name)
</P>
<H5>Description</H5>
<P>
Set the attribute name.
Freeing the attribute will free this string, so it should be
created with malloc/calloc.
</P>
<H4><A NAME="HTMLSetAData">HTMLSetAData</A></H4>
<H5>Usage</H5>
<P>
HTMLSetAData(attribute, _data)
</P>
<H5>Description</H5>
<P>
Set the attribute value.
Freeing the attribute will free this string, so it should be
created with malloc/calloc.
</P>
<H4><A NAME="HTMLSetANext">HTMLSetANext</A></H4>
<H5>Usage</H5>
<P>
HTMLSetANext(attribute, _next)
</P>
<H5>Description</H5>
<P>
Set the next attribute in the markup's list.
This does not do insertion, but simply sets the value of the
next field in the structure.
</P>
<H4><A NAME="HTMLSetALineno">HTMLSetALineno</A></H4>
<H5>Usage</H5>
<P>
HTMLSetALineno(attr, _lineno)
</P>
<H5>Description</H5>
<P>
Set the source file line number.
Use 0 for dynamically created attributes.
</P>

<H3>Attribute Functions</H3>
<P>
The attribute function calls are used mostly to modify a document
parse tree.
They provide creation/destruction, modification, and lookup functions.
</P>
<H4><A NAME="HTMLNewAttr">HTMLNewAttr</A></H4>
<H5>Usage</H5>
<P>
Attribute *HTMLNewAttr(char *name, char *value, int lineno);
</P>
<H5>Description</H5>
<P>
Create a new attribute structure.
</P>

<H4><A NAME="HTMLFreeAttribute">HTMLFreeAttribute</A></H4>
<H5>Usage</H5>
<P>
void HTMLFreeAttribute(Attribute *old);
</P>
<H5>Description</H5>
<P>
Free a single attribute structure.
This function does not free any other attributes in the
attribute list -- use HTMLFreeAttributeList to do that.
</P>

<H4><A NAME="HTMLFreeAttributeList">HTMLFreeAttributeList</A></H4>
<H5>Usage</H5>
<P>
void HTMLFreeAttributeList(Attribute *old);
</P>
<H5>Description</H5>
<P>
Free the attribute and all others in the list.
</P>

<H4><A NAME="HTMLGetAttr">HTMLGetAttr</A></H4>
<H5>Usage</H5>
<P>
char *HTMLGetAttr(Block *bp, char *name);
</P>
<H5>Description</H5>
<P>
Given a markup block, and a name string, HTMLGetAttr() will return
the value associated with that name.
0 will be returned if 'name' is not found in the attribute list.
The search for 'name' will be case-insensitive.
</P>

<H4><A NAME="HTMLSetAttr">HTMLSetAttr</A></H4>
<H5>Usage</H5>
<P>
void HTMLSetAttr(Block *bp, char *name, char *data);
</P>
<H5>Description</H5>
<P>
Given a markup block, and a name string, HTMLSetAttr() will find
the appropriate attribute and set the new value.
There are no provisions for error handling.
</P>

<H4><A NAME="HTMLRemoveAttr">HTMLRemoveAttr</A></H4>
<H5>Usage</H5>
<P>
int HTMLRemoveAttr(Block *bp, char *name);
</P>
<H5>Description</H5>
<P>
Remove the attribute with the given name from the Block *bp.
</P>

<HR>
<H2>Error Handling</H2>
<P>
Error handling is handler based so that the calling program can
intervene in different ways.
</P>

<H3>Error Structure</H3>
<PRE><CODE>
struct error {
    int lineno;			/* Line number of offending string */
    int severity;		/* How severe the error is */
    char *text;			/* Text of offending character */
    int type;			/* Error type */
    char *message;		/* Generated error message */
};
</CODE></PRE>

<DL>
<DT>lineno</DT>
<DD>Line number the error was detected on.</DD>
<DT>severity</DT>
<DD>The parser's estimate of the error's severity</DD>
<DT>text</DT>
<DD>The characters causing the error, if available.</DD>
<DT>type</DT>
<DD>The explicit error type.</DD>
<DT>message</DT>
<DD>The parser's generated message.</DD>
</DL>

<H3>Error Severities</H3>
<DL>
<DT>E_INFORMATION</DT>
<DD>Usually notes optional missing elements being provided.
Technically not an error.</DD>
<DT>E_WARNING</DT>
<DD>The parser is allowing something that violates a strict
interpretation of the HTML spec.</DD>
<DT>E_SEVERE</DT>
<DD>A syntax error has been ignored.
Usually the parser can recover from this, but the resulting parse
tree is pretty bogus.</DD>
<DT>E_CRASH</DT>
<DD>Something severe enough has happened to threaten the integrity
of the parser.
Usually any further parsing will risk crashing the program.</DD>
</DL>

<H3>Error Types</H3>

<DL>
<DT>E_UNEXPECTEDCHAR</DT>
<DD>An unexpected (or illegal) character has appeared in the
input stream.</DD>
<DT>E_NOMEM</DT>
<DD>An attempt to allocate memory has failed.</DD>
<DT>E_MISSINGHTML</DT>
<DD>The opening &lt;HTML> (which is optional) was not supplied.</DD>
<DT>E_MISSINGHEAD</DT>
<DD>The opening &lt;HEAD> (which is optional) was not supplied.</DD>
<DT>E_MISSINGBODY</DT>
<DD>The opening &lt;BODY> (which is optional) was not supplied.</DD>
<DT>E_CANTCLOSE</DT>
<DD>We have an element that is parented by an element which
requires a manditory close.  This element is not an
appropriate child for this parent.  We parent the element
anyway.</DD>
<DT>E_BADPARENT</DT>
<DD>While moving up the list closing elements and looking for
a valid parent, we found an element requiring a manditory
close.  This is a syntax error.  We will parent the child
at the lowest level and go on.</DD>
<DT>E_NOCLOSE</DT>
<DD>An element is missing its mandatory end tag.</DD>
<DT>E_NOOPEN</DT>
<DD>An end tag has no corresponding opening element.</DD>
<DT>E_UNKNOWNELE</DT>
<DD>An unknown element has been found.  We assume that these
must be terminated and can contain any other elements.</DD>
<DT>E_SYNTAX</DT>
<DD>Yacc has detected a syntax error.</DD>
<DT>E_MISSINGTITLE</DT>
<DD>HTML requires a title.  This error indicates that none
was provided.</DD>
<DT>E_PROGRAMMING</DT>
<DD>An illegal usage of one of the builtin programming functions.</DD>
<DT>E_UNKNOWNATTR</DT>
<DD>An unknown attribute has been found.</DD>
<DT>E_INVALIDEATTR</DT>
<DD>Attribute is not allowed in the markup it is found in.</DD>
<DT>E_MISSINGATTR</DT>
<DD>Required attribute is missing in this markup.</DD>
<DT>E_UNKNOWNENTITY</DT>
<DD>Unknown entity name.</DD>
<DT>E_ATTR</DT>
<DD>Unknown entity name possibly resulting in some of the
attribute line being lost.</DD>
<DT>E_MISSINGQUOTE</DT>
<DD>Apparently missing quote in attribute list.  Although this
may have been someone embedding a '>' in the quoted string,
it is more often just an error, so we try to fix it.</DD>
<DT>E_EXTRATAG</DT>
<DD>A tag that should only appear once (like &lt;HTML> or &lt;BODY>)
has appeared twice.</DD>
<DT>E_COMMENTTERM</DT>
<DD>No terminating tag was found for a comment in the source.  This can
exclude much of the source from the tree.</DD>
</DL>

<H3>Default Error Handler</H3>
<P>
The default error handler writes an error message to stderr.
It can be overridden by a developer specified error handler.
</P>
<PRE><CODE>
static int
_DefaultHTMLError(struct error *errp)
{
    char *type;
	 
    if (errp->severity > E_WARNING)
	type = "Error";
    else
	type = "Warning";

    fprintf(stderr, "%s: %d: %s\n", type, errp->lineno, errp->message);

    return (1);
}

</CODE></PRE>

<H3>Error Functions</H3>
<H4><A NAME="HTMLSetErrorHand">HTMLSetErrorHand</A></H4>
<H5>Usage</H5>
<P>
HTMLErrorHandler HTMLSetErrorHand(HTMLErrorHandler);
<H5>Description</H5>
<P>
Sets a new handler function and returns the previous one.
<DL>
<DT>The functions type is:</DT>
<DD>typedef int (*HTMLErrorHandler)(struct error *errp);</DD>
</DL>

<HR>
</BODY>
</HTML>
